package com.hermes.biz.search.search;
import org.apache.lucene.search.BooleanClause;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKSimilarity;

import com.hermes.biz.common.model.item.ItemDO;
import com.hermes.biz.search.index.IndexManager;
import javax.annotation.Resource;

public class SearchManager {

	IndexManager indexManager;
	
	public IndexManager getIndexManager() {
		return indexManager;
	}
	public void setIndexManager(IndexManager indexManager) {
		this.indexManager = indexManager;
	}
	public IndexSearcher getSearcher(){
		IndexSearcher searcher = null;
    	try{
    		File indexFile = new File(indexManager.getIndexDir());
    		searcher = new IndexSearcher(FSDirectory.open(indexFile));
    	}catch(IOException e){
    		
    	}
    	return searcher;
	}
	 public List<ItemDO> getItemSearchResult(String queryStr,int topN) throws Exception{
	    	List<ItemDO> result = null;	    	
	    	TopScoreDocCollector results = createResult(queryStr, topN);
	    	int rstCount = results.getTotalHits();	    	
	    	if(rstCount<topN){
	    		TopDocs topDocs = this.searchTopN(queryStr, rstCount, results);
	    		ScoreDoc[] scoreDocs = topDocs.scoreDocs;     
		        result = this.addItemHits2List(scoreDocs,getSearcher());     
		        return result;
	    	}else{
	    		TopDocs topDocs = this.searchTopN(queryStr, topN, results);
	    		ScoreDoc[] scoreDocs = topDocs.scoreDocs;     
		        result = this.addItemHits2List(scoreDocs,getSearcher());     
		        return result;
	    	}
	    	
	    }
	 public TopScoreDocCollector createResult(String queryStr,int topN) throws ParseException, IOException{
			IndexSearcher searcher = getSearcher();   
	         searcher.setSimilarity(new IKSimilarity());     
	         //QueryParser parser = new QueryParser(Version.LUCENE_30,"item_title",new IKAnalyzer());  
	         //Query query = parser.parse(queryStr);  
	         //multifieldQueryParser
	         //two fileds two query
	         //Query query = MultiFieldQueryParser.parse(Version.LUCENE_30, new String[]{queryStr,queryStr}, new String[]{"item_title","description"}, new IKAnalyzer());//.Parse(Version.LUCENE_30,new String[]{"item_title","description"},new IKAnalyzer());
	        // afield or bfield
	         BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD }; 
	         Query query = MultiFieldQueryParser.parse(Version.LUCENE_30, queryStr, new String[]{"item_title","description"}, clauses , new IKAnalyzer());
	        
	         TopScoreDocCollector results = TopScoreDocCollector.create(searcher.maxDoc(), false);
	         searcher.search(query, results);
	         return results;
	 }
	    private TopDocs searchTopN(String queryStr,int topN,TopScoreDocCollector results) throws Exception {
	    	if(topN>=18){
	    		TopDocs topDocs = results.topDocs(topN, 18);
	    		return topDocs;  
	    	}else{
	    		TopDocs topDocs = results.topDocs(0, topN);
	    		return topDocs;  
	    	}
	     }  
	    
	    private List<ItemDO> addItemHits2List(ScoreDoc[] scoreDocs ,IndexSearcher searcher) throws Exception {     
	        List<ItemDO> listBean = new ArrayList<ItemDO>();     
	        ItemDO bean = null;     
	        for(int i=0 ; i<scoreDocs.length; i++) {     
	            int docId = scoreDocs[i].doc;     
	            Document doc = searcher.doc(docId);     
	            bean = new ItemDO();     
	            bean.setItemId(Long.valueOf(doc.get("item_id").toString()));//.setItemPicUrl(doc.get("picture_url"));
	            bean.setItemPicUrl(doc.get("picture_url"));
	            bean.setTagId(Integer.parseInt(doc.get("tag_id")));
	            bean.setItemTitle(doc.get("item_title")); 
	            bean.setDescription(doc.get("description"));
	            listBean.add(bean);     
	        }     
	        return listBean;     
	    } 
}
